package gnss

import (
	"gitee.com/ymofen/gobase"
	"sync"
	"time"
)

type EphItem struct {
	pubcnt      int32
	UUID        string
	PrnNo       string
	naviSysCode string
	eph         *RtcmEph
	ValidFlag   int8
	disableflag int8
	RtcmBuf     []byte
	startt      time.Time
	LastUptime  time.Time
	TagStr      string
}

func (this *EphItem) GetEph() *RtcmEph {
	return this.eph
}

type GnssEphlst struct {
	lk         sync.RWMutex
	lst        map[string]*EphItem
	uuidFunc   func(eph *RtcmEph) string
	CheckValid int8
	OnNewEph   func(itm *EphItem)
}

func NewGnssEphlst() *GnssEphlst {
	rval := &GnssEphlst{CheckValid: 1}
	rval.lst = make(map[string]*EphItem)
	rval.uuidFunc = func(eph *RtcmEph) string {
		return eph.MakeUUIDEx()
	}
	return rval
}

func (this *GnssEphlst) Clean() {
	this.lk.Lock()
	defer this.lk.Unlock()
	for k, _ := range this.lst {
		delete(this.lst, k)
	}
}

// 只保留有效期内的星历
func (this *GnssEphlst) ClearCache(start, end time.Time) {
	this.lk.Lock()
	defer this.lk.Unlock()
	for k, v := range this.lst {
		if (!start.IsZero() && v.eph.Time.Before(start)) || (!end.IsZero() && v.eph.Time.After(end)) {
			delete(this.lst, k)
		}
	}
}

func (this *GnssEphlst) DefaultUUIDFunc(eph *RtcmEph) string {
	return eph.MakeUUIDEx()
}

func (this *GnssEphlst) ConfigUUIDFunc(fn func(eph *RtcmEph) string) {
	if fn == nil {
		this.uuidFunc = this.DefaultUUIDFunc
	} else {
		this.uuidFunc = fn
	}
}

func (this *GnssEphlst) checkEphValid(itm *EphItem) {
	eph := itm.eph
	if eph.Sys == SYS_GPS {
		if eph.Satid <= 0 && eph.Satid > 32 { // 陶俊
			itm.ValidFlag = -1
			return
		}
	}
	err := eph.CheckSatIdInvalid()
	if err != nil {
		itm.ValidFlag = -1
		return
	}
	if eph.RnxTime().Second() != 0 { // 不是整秒的星历过滤掉
		itm.ValidFlag = -2
		return
	}
}

func (this *GnssEphlst) InputEph(eph *RtcmEph, rtcmBuf []byte, tagstr string) {
	eph.DecodeEphTime()
	ephUUID := this.uuidFunc(eph)

	this.lk.RLock()
	itm := this.lst[ephUUID]
	this.lk.RUnlock()

	if itm != nil {
		itm.LastUptime = time.Now()
		itm.TagStr = tagstr
		return
	}

	itm = &EphItem{UUID: ephUUID, eph: eph, ValidFlag: 0, RtcmBuf: gobase.CloneBytes(rtcmBuf, 0, 0), LastUptime: time.Now(), startt: time.Now(), TagStr: tagstr}
	itm.naviSysCode = GetNavSysCode(eph.Sys)
	itm.PrnNo = eph.GetPrnStrCode()
	itm.LastUptime = time.Now()
	itm.TagStr = tagstr

	if this.CheckValid == 1 { // 检测数据是否有效
		this.checkEphValid(itm)
	}

	flag := 0

	this.lk.Lock()
	itm0 := this.lst[ephUUID]
	if itm0 == nil {
		this.lst[ephUUID] = itm
		flag = 1
	}
	this.lk.Unlock()

	if flag == 1 {
		evt := this.OnNewEph
		if evt != nil {
			evt(itm)
		}
	}

}
